package com.usian.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sun.tools.javac.util.Pair;
import com.usian.admin.feign.ArticleFeign;
import com.usian.admin.feign.WemediaFeign;
import com.usian.admin.mapper.AdChannelMapper;
import com.usian.admin.mapper.AdSensitiveMapper;
import com.usian.admin.service.WemediaNewsAutoScanService;
import com.usian.common.aliyun.scan.GreeTextScan;
import com.usian.common.aliyun.scan.GreenImageScan;
import com.usian.common.fastdfs.FastDFSClient;
import com.usian.common.wemedia.WemediaContans;
import com.usian.jwt.utils.common.SensitiveWordUtil;
import com.usian.model.admin.pojos.AdChannel;
import com.usian.model.admin.pojos.AdSensitive;
import com.usian.model.article.pojo.ApArticle;
import com.usian.model.article.pojo.ApArticleConfig;
import com.usian.model.article.pojo.ApArticleContent;
import com.usian.model.base.BaseServiceImpl;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.media.pojos.WmUser;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class WemediaNewsAutoScanServiceImpl extends BaseServiceImpl<AdSensitiveMapper, AdSensitive>implements WemediaNewsAutoScanService {
    @Autowired
    private WemediaFeign wemediaFeign;
    @Autowired
    private ArticleFeign articleFeign;
    @Value("${fdfs.url}")
    private String baseUrl;
    @Autowired
    private GreeTextScan textScan;
    @Autowired
    private GreenImageScan imageScan;
    @Autowired
    private FastDFSClient fastDFSClient;
    @Autowired
    private AdChannelMapper adChannelMapper;

   private short resultStatus = WmNews.Status.PUBLISHED.getCode();
  private   String reason="审核通过";
    @Override
    public ResponseResult autoScanByMediaNewsId(Integer id) {
        if (id==null)return errorParam;

        boolean isGoing=true;
        WmNews news = wemediaFeign.findById(id);
        if (news.getStatus().equals(WmNews.Status.SUBMIT.getCode())){
            Pair<StringBuffer, List<String>> controlData = getControlData(news);
            String text= controlData.fst.toString();
            //本文自动审核
            try {
             Map map=textScan.greeTextScan(text);
                isGoing=isGoing(map,news);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //图片审核
            if (isGoing){//通过了
                isGoing=isGoing(imageAutoScan(controlData.snd),news);
            }
            //敏感词匹配
            if (isGoing){
                List<String> allSensitive = baseMapper.findAllSensitive();
                SensitiveWordUtil.initMap(allSensitive);
                Map<String, Integer> map = SensitiveWordUtil.matchWords(text);
                if (map.size()!=0){//有敏感词
                    HashMap<String, Object> tempMap = new HashMap<>();
                    tempMap.put("suggestion","block");
                 isGoing=  isGoing(tempMap,news);
                }
            }
        }
        if (isGoing){//自动审核通过
            if (news.getPublishTime().getTime()<=System.currentTimeMillis()){
               ApArticle apArticle= saveArticle(news);
               saveArticleConfig(apArticle);
               saveArticleContent(apArticle,news);

            }else {
                reason="审核通过待发布";
                resultStatus=WmNews.Status.SUCCESS.getCode();
            }
            updateNewStatus(news,reason,resultStatus);
        }
        return isGoing ? ResponseResult.okResult(reason):ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,reason);
    }

    //从新闻内容中提取审核的文本和图片
    private Pair<StringBuffer,List<String>> getControlData(WmNews news){
        String content = news.getContent();
        JSONArray array = JSON.parseArray(content);
        StringBuffer buffer = new StringBuffer();
        ArrayList<String> urlList = new ArrayList<>();
        array.forEach(a->{
            JSONObject object = JSON.parseObject(a.toString());
            String value = object.getString("value");
            if (object.get("type").equals("image")){
                urlList.add(value.replace(baseUrl,""));

            }else {
                buffer.append(value);
            }
        });
        if (news.getType() == WemediaContans.WM_NEWS_SINGLE_IMAGE){
            urlList.add(news.getImages().replace(baseUrl,""));
        }else  if (news.getType()==WemediaContans.WM_NEWS_MANY_IMAGE){
            String[] split = news.getImages().split("，");
            for (String s : split) {
                urlList.add(s.replace(baseUrl,""));
            }
        }
       return new Pair<>(buffer,urlList);

    }

   //图片自动审核
    private Map imageAutoScan(List<String> urlList){
        ArrayList<byte[]> bytes = new ArrayList<>();
        for (String s : urlList) {
            int i = s.indexOf("/");
            String groupName = s.substring(0, i);
            s+="0";
            String path = s.substring(i + 1, s.length() - 1);
            try {
                byte[] download= fastDFSClient.download(groupName,path);
                bytes.add(download);

            }  catch (Exception e) {
                e.printStackTrace();
            }
        }
        Map map=null;
        try {
            map = imageScan.imageScan(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    private void saveArticleContent(ApArticle apArticle,WmNews news){
        ApArticleContent apArticleContent = new ApArticleContent();
        apArticleContent.setArticleId(apArticle.getId());
        apArticleContent.setContent(news.getContent());
        articleFeign.saveArticleContent(apArticleContent);
    }

    private void saveArticleConfig(ApArticle apArticle){
        ApArticleConfig config = new ApArticleConfig();
        config.setArticleId(apArticle.getId());
        config.setIsComment(false);
        config.setIsForward(false);
        config.setIsDown(false);
        config.setIsDelete(false);
        articleFeign.saveArticleConfig(config);
    }

    private ApArticle saveArticle(WmNews news){
        Integer userId = news.getUserId();
        WmUser wmUser = wemediaFeign.getUserById(userId);
        AdChannel adChannel = adChannelMapper.selectById(news.getChannelId());
        ApArticle apArticle = new ApArticle();
        apArticle.setTitle(news.getTitle());
        apArticle.setAuthorId(wmUser.getApAuthorId().longValue());
        apArticle.setAuthorName(wmUser.getName());
        apArticle.setChannelId(news.getChannelId());
        apArticle.setChannelName(adChannel.getName());
        apArticle.setLayout(news.getType());
        if (news.getType()==WemediaContans.WM_NEWS_MANY_IMAGE)apArticle.setLayout((short) 2);
        apArticle.setFlag((byte) 0);
        apArticle.setImages(news.getImages());
        apArticle.setLikes(0);
        apArticle.setCollection(0);
        apArticle.setViews(0);
        apArticle.setComment(0);
        apArticle.setCreatedTime(news.getCreatedTime());
        apArticle.setPublishTime(news.getPublishTime());
       return articleFeign.saveArticle(apArticle);
    }
    private boolean isGoing(Map map, WmNews news){
        if (!map.get("suggestion").equals("pass")){
            if (map.get("suggestion").equals("block")){//建议拒绝
                reason ="审核失败";
                resultStatus  = WmNews.Status.FAIL.getCode();
                updateNewStatus(news,reason,resultStatus);
            }else if(map.get("suggestion").equals("review")){
                reason ="人工审核";
                resultStatus=WmNews.Status.ADMIN_AUTH.getCode();

                updateNewStatus(news,reason,resultStatus);
            }
            return false;
        }
        return true;
    }

    private void updateNewStatus(WmNews news, String reason, short sataus){
        WmNews updateNews = new WmNews();
        updateNews.setId(news.getId());
        updateNews.setStatus(sataus);
        updateNews.setReason(reason);
        wemediaFeign.updateWmNews(updateNews);
    }

}
